package com.mistralcoast.rule34;

import java.beans.PropertyChangeEvent;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

public class MainPage extends Activity {
	private static SQLiteDatabase db;
	protected DatabaseHelper dbHelper;
	/** Called when the activity is first created. */
	TagFetcher tf = new TagFetcher() {

		public void propertyChange(PropertyChangeEvent event) {
			// TODO Auto-generated method stub

		}

		@Override
		protected Boolean doInBackground(Void... params) {
			// TODO Auto-generated method stub
			return null;
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		dbHelper = new DatabaseHelper(this, this);
		initialiseDatabase();
//		dbHelper.onUpgrade(db, 0, 1);
		setContentView(R.layout.main);
		AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete_tag);
		Cursor c = dbHelper.getDefaultCursor();
		MySuggestionsAdapter adapter = new MySuggestionsAdapter(this, c);
		textView.setOnClickListener(null);
		textView.setAdapter(adapter);
	}

	private void initialiseDatabase() {
		try {
			dbHelper.createDataBase();
		} catch (IOException ioe) {
			throw new Error("Unable to create database");
		}
		try {
			dbHelper.openDataBase();
		} catch (SQLException sqle) {
			throw sqle;
		}
	}

	class DatabaseHelper extends SQLiteOpenHelper {
		private static final String DB_PATH = "/data/data/com.mistralcoast.rule34/databases/";
		private static final String DATABASE_NAME = "rule34";
		private static final String TABLE_NAME = "tags";
		private static final int DATABASE_VERSION = 1;
		private SQLiteDatabase myDataBase;

		Context context;
		Activity activity;

		DatabaseHelper(Context context, Activity activity) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
			this.context = context;
			this.activity = activity;
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			final String DATABASE_CREATE_STATES = "create table IF NOT EXISTS "
					+ TABLE_NAME + "(_id integer primary key autoincrement"
					+ ", tagName text not null)";
			db.execSQL(DATABASE_CREATE_STATES);
			populateWithData(db);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
			onCreate(db);
		}

		private void populateWithData(SQLiteDatabase db) {
			ArrayList<String> tags = tf.getTagsFromFile(activity);

			try {
				db.beginTransaction();
				ContentValues values = new ContentValues();
				for (String s : tags) {
					values.put("tagName", s);
					db.insertOrThrow(TABLE_NAME, "tagName", values);
				}
				db.setTransactionSuccessful();
			} catch (SQLException e) {
				System.err.println("Could not insert tag into database : " + e);
			} finally {
				db.endTransaction();
			}
		}

		public Cursor getMatchingTags(String matchString) throws SQLException {
			Cursor cursor = db.query(TABLE_NAME, new String[] { "_id","tagName" },
					"tagName LIKE '" + matchString +"%'", null, null, null, null);
			if (cursor != null) {
				cursor.moveToFirst();
				return cursor;
			}
			return cursor;
		}

		public Cursor getDefaultCursor() throws SQLException {
			Log.d("Rule34", "getDefaultCursor...");
			Cursor cursor = db.query(TABLE_NAME, new String[] { "_id","tagName" },
					null, null, null, null, null);
			if (cursor != null) {
				cursor.moveToFirst();
				return cursor;
			}
			return cursor;
		}

		public SQLiteDatabase getDatabase() {
			String myPath = DB_PATH + DATABASE_NAME;
			return SQLiteDatabase.openDatabase(myPath, null,
					SQLiteDatabase.OPEN_READONLY);
		}

		public void createDataBase() throws IOException {
//			context.deleteDatabase(DATABASE_NAME); //when upgrading
			Log.d("Rule34", "Creating Database...");
			boolean dbExist = checkDataBase();
			if (!dbExist) {
				this.getReadableDatabase();
				try {
					copyDataBase();
				} catch (IOException e) {
					throw new Error("Error copying database");
				}
			}
		}
		
		public void openDataBase() throws SQLException {
			Log.d("Rule34", "Opening Database...");
			// Open the database
			String myPath = DB_PATH + DATABASE_NAME;
			db = SQLiteDatabase.openDatabase(myPath, null,
					SQLiteDatabase.OPEN_READONLY);
		}

		private void copyDataBase() throws IOException {
			Log.d("Rule34", "Copying Database...");
			// Open your local db as the input stream
			
			AssetManager assetManager = activity.getAssets();
			InputStream myInput = assetManager.open(DATABASE_NAME);

			// Path to the just created empty db
			String outFileName = DB_PATH + DATABASE_NAME;

			// Open the empty db as the output stream
			OutputStream myOutput = new FileOutputStream(outFileName);

			// transfer bytes from the inputfile to the outputfile
			byte[] buffer = new byte[1024];
			int length;
			while ((length = myInput.read(buffer)) > 0) {
				myOutput.write(buffer, 0, length);
			}

			// Close the streams
			myOutput.flush();
			myOutput.close();
			myInput.close();
		}

		private boolean checkDataBase() {
			Log.d("Rule34", "checkDataBase...");
			SQLiteDatabase checkDB = null;
			try {
				String myPath = DB_PATH + DATABASE_NAME;
				checkDB = SQLiteDatabase.openDatabase(myPath, null,
						SQLiteDatabase.OPEN_READONLY);
			} catch (SQLiteException e) {
				e.printStackTrace();
			}
			if (checkDB != null) {
				checkDB.close();
			}
			return checkDB != null ? true : false;
		}

		

		@Override
		public synchronized void close() {
			if (myDataBase != null)
				myDataBase.close();

			super.close();
		}
	}

	class MySuggestionsAdapter extends CursorAdapter {
		Context context;

		public MySuggestionsAdapter(Context context, Cursor c) {
			super(context, c);
			this.context = context;
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			System.out.println("Got to bindView");
			int columnIndex = cursor.getColumnIndexOrThrow("tagName");
			((TextView) view).setText(cursor.getString(columnIndex));
		}

		@Override
		public String convertToString(Cursor cursor) {
			System.out.println("Got to convertToString");
			int columnIndex = cursor.getColumnIndexOrThrow("tagName");
			return cursor.getString(columnIndex);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			System.out.println("Got to newView");
			final LayoutInflater inflater = LayoutInflater.from(context);
			final TextView view = (TextView) inflater.inflate(
					android.R.layout.simple_dropdown_item_1line, parent, false);
			int columnIndex = cursor.getColumnIndexOrThrow("tagName");
			view.setText(cursor.getString(columnIndex));
			return view;
		}

		@Override
		public Cursor runQueryOnBackgroundThread(CharSequence matchString) {
			if(null == matchString) return dbHelper.getMatchingTags("Aki");
			System.out.println("Got to runQueryOnBackgroundThread");
			return dbHelper.getMatchingTags(matchString.toString());
		}
	}
}
